﻿using MvvmCross.Core.ViewModels;
using MvvmCross.Platform;
using Sidvall.IdentityManager.UI.ViewModels;
using Sidvall.UI.Wpf.Presenters;
using System.Linq;
using System.Windows;

namespace Sidvall.IdentityManager.UI.Wpf
{
    public static class Program
    {
        #region Public Members

        public static void OnActivated(App item)
        {
            if (!Sidvall.UI.SystemContext.Current.ApplicationManager.SetupCompleted)
                DoSetup(item);
        }

        #endregion
        #region Private Members

        #region AssemblyResolveEventHandler

        private static System.Reflection.Assembly AssemblyResolveEventHandler(object sender, System.ResolveEventArgs args)
        {
            System.Collections.Generic.IEnumerable<System.Reflection.Assembly> items;
            System.Reflection.Assembly item;

            items = System.AppDomain.CurrentDomain.GetAssemblies();
            item = (from o in items
                    where (o.FullName == args.Name)
                    select o).FirstOrDefault();
            if (item == null)
            {
                items = System.AppDomain.CurrentDomain.GetAssemblies();
                item = (from o in items
                        where (o.GetName().Name == args.Name)
                        select o).FirstOrDefault();
            }
            return item;
        }

        #endregion
        #region DoSetup

        private static void DoSetup(Application app)
        {
            MainWindow windows;

            RegisterTypes();

            // Initializing
            Sidvall.UI.Wpf.SystemContext.Current.MainWindow = app.MainWindow;
            Sidvall.UI.SystemContext.Current.NavigationManager.MaxHistoryItemCount = 10;
            System.AppDomain.CurrentDomain.AssemblyResolve += new System.ResolveEventHandler(AssemblyResolveEventHandler);
            var presenter = new RegionPresenter();
            var setup = new Setup(app.Dispatcher, presenter);
            setup.Initialize();
            windows = (MainWindow)Sidvall.UI.Wpf.SystemContext.Current.MainWindow;
            var model = new MainWindowViewModel();
            model.Start(Properties.Settings.Default.ApplicationTitle);
            windows.ViewModel = model;

            // Starting
            Sidvall.UI.SystemContext.Current.ApplicationManager.Status = Sidvall.UI.ApplicationStatus.Starting;
            var start = Mvx.Resolve<IMvxAppStart>();
            start.Start();
            Sidvall.UI.SystemContext.Current.ApplicationManager.SetupCompleted = true;
        }

        #endregion
        #region RegisterTypes

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling")]
        private static void RegisterTypes()
        {
            // Framework
            var authorizationProvider = new Sidvall.Security.PublicAuthorizationProvider();
            Sidvall.SystemContext.Current = new Sidvall.SystemContext()
            {
                //AccountManager = new Sidvall.Security.AccountManager(new Sidvall.IdentityManager.Security.AccountProvider()),
                AuthorizationManager = new Sidvall.Security.AuthorizationManager(authorizationProvider),
                AuthenticationManager = new Sidvall.Security.AuthenticationManager(new Sidvall.Security.AuthenticationProvider()),
                AuthenticationStrategyManager = new Sidvall.Security.AuthenticationStrategyManager(new Sidvall.Security.AuthenticationStrategy()),
                CacheManager = new Sidvall.Caching.CacheManager(new Sidvall.Caching.MemoryCache()),
                ClaimManager = new Sidvall.Security.ClaimManager(new Sidvall.Security.ClaimsPrincipalManager()),
                CodeManager = new Sidvall.Reflection.CodeManager(new Sidvall.Reflection.Code()),
                UserExceptionManager = new Sidvall.ExceptionHandling.ExceptionManager(new Sidvall.ExceptionHandling.UserExceptionProvider()),
                SystemExceptionManager = new Sidvall.ExceptionHandling.ExceptionManager(new Sidvall.ExceptionHandling.SystemExceptionProvider()),
                HttpClientFactory = new Sidvall.Net.HttpClientFactory(),
                LauncherManager = new Sidvall.SystemEnvironment.LauncherManager(new Sidvall.SystemEnvironment.Windows.Launcher()),
                LogManager = new Sidvall.Logging.LogManager(new Sidvall.Logging.LogCollection()),
                PackageManager = new Sidvall.SystemEnvironment.PackageManager(new Sidvall.SystemEnvironment.Windows.Package()),
                //SmsClientManager = new Sidvall.Net.Sms.SmsClientManager(new Sidvall.Net.Sms.SmsClient("")),
                SmtpClientManager = new Sidvall.Net.Mail.SmtpClientManager(new Sidvall.Net.Mail.SmtpClient()),
                SoapClientFactory = new Sidvall.Net.SoapClientFactory(),
                SqlManager = new Sidvall.Data.SqlManager(new Sidvall.Data.SqlServerProvider()),
                SystemStorageManager = new Sidvall.IO.StorageManager(new Sidvall.IO.FileSystem()),
                TransactionScopeFactory = new Sidvall.Data.TransactionScopeFactory(),
                TypeCache = new Sidvall.Reflection.TypeCache(),
                UserManager = new Sidvall.Security.UserManager(authorizationProvider),
                UserResponseStrategyManager = new Sidvall.Security.UserResponseStrategyManager(new Sidvall.Security.UserResponseStrategy()),
                UserStorageManager = new Sidvall.IO.StorageManager(new Sidvall.IO.FileSystem(Sidvall.IO.FolderType.LocalApplicationData)),

                // Client
                PrincipalContextManager = new Sidvall.Security.PrincipalContextManager(new Sidvall.Security.PrincipalContextProvider()),
                PrincipalManager = new Sidvall.Security.PrincipalManager(new Sidvall.Security.PrincipalProvider()),

                // Host specific
                CultureManager = new Sidvall.Globalization.CultureManager(new Sidvall.UI.Wpf.Globalization.CultureProvider()),
                ResourceManager = new Sidvall.Resources.ResourceManager(new Sidvall.Resources.ResourceProvider()),
                SettingsManager = new Sidvall.Configuration.SettingsManager(new Sidvall.IdentityManager.UI.Wpf.Configuration.ApplicationSettings()),
            };
            Sidvall.IdentityManager.SystemContext.Current.InitializeAuthenticationStrategy();
            Sidvall.UI.SystemContext.Current = new Sidvall.UI.SystemContext()
            {
                ApplicationManager = new Sidvall.UI.ApplicationManager(),
                ConfigurationContext = new Sidvall.UI.Configuration.ConfigurationContext(new Sidvall.UI.Wpf.Views.ContentControlRegionManager()),
                DialogManager = new Sidvall.UI.Dialogs.DialogManager(
                    new Sidvall.UI.Wpf.Dialogs.FileDialog(),
                    new Sidvall.UI.Wpf.Dialogs.FolderDialog(),
                    new Sidvall.UI.Wpf.Dialogs.MessageDialogManager(),
                    new Sidvall.UI.Wpf.Dialogs.MessageBoxDialog(),
                    new Sidvall.UI.Wpf.Dialogs.SecurityDialogManager(),
                    new Sidvall.UI.Wpf.Dialogs.ProgressDialogManager(),
                    new Sidvall.UI.Wpf.Dialogs.WebDialogManager()),
                NavigationManager = new Sidvall.UI.Navigation.NavigationManager(),
            };

            // Application specific
            Sidvall.IdentityManager.SystemContext.Current.InitializeClientDataLayer();
        }

        #endregion

        #endregion
    }
}
